import 'dart:math';
import 'package:flutter/material.dart';
import 'dart:ui' as ui show window;

class Barrage {
  static List<OverlayEntry> list = [];

  static void emit({
    required BuildContext context,
    required Widget child,
  }) {
    late OverlayEntry _barrage;

    _barrage = OverlayEntry(
      builder: (BuildContext context) {
        return _RandomPositioned(
          child: _BarrageItem(
            child: child,
            onFinal: () {
              list.remove(_barrage);
              _barrage.remove();
            },
          ),
        );
      },
    );

    Overlay.of(context)!.insert(_barrage);

    list.add(_barrage);
  }

  static void remove() {
    list.forEach((element) {
      element.remove();
    });
    list = [];
  }
}

class _RandomPositioned extends StatefulWidget {
  final Widget child;

  _RandomPositioned({
    Key? key,
    required this.child,
  }) : super(key: key);

  @override
  _RandomPositionedState createState() => _RandomPositionedState();
}

class _RandomPositionedState extends State<_RandomPositioned> {
  // 获取范围随机数
  double _getRange() {
    MediaQueryData mediaQuery = MediaQueryData.fromWindow(ui.window);
    double min = mediaQuery.padding.top;
    double max = 200;

    return min + Random().nextInt((max - min).toInt() + 1);
  }

  double _top = 0;

  @override
  void initState() {
    super.initState();

    _top = _getRange();
  }

  @override
  Widget build(BuildContext context) {
    return Positioned(
      top: _top,
      right: 0,
      child: widget.child,
    );
  }
}

class _BarrageItem extends StatefulWidget {
  final Widget child;
  final Function? onFinal;

  _BarrageItem({
    Key? key,
    required this.child,
    this.onFinal,
  }) : super(key: key);

  @override
  _BarrageItemState createState() => _BarrageItemState();
}

class _BarrageItemState extends State<_BarrageItem>
    with SingleTickerProviderStateMixin {
  GlobalKey _key = GlobalKey();

  late AnimationController _controller;

  Animation<double>? _animation;

  Duration _duration = Duration(seconds: 4);

  @override
  void initState() {
    super.initState();

    MediaQueryData mediaQuery = MediaQueryData.fromWindow(ui.window);
    // 移动距离 = 屏幕宽度
    double moveDist = mediaQuery.size.width;

    WidgetsBinding.instance!.addPostFrameCallback((_) {
      RenderObject renderObject = _key.currentContext!.findRenderObject()!;
      Rect rect = renderObject.semanticBounds;
      // 移动距离 = 屏幕宽度 + 弹幕宽度
      moveDist += rect.width;

      _controller = AnimationController(
        vsync: this,
        duration: _duration,
      );

      _animation = Tween<double>(
        begin: 0,
        end: -moveDist,
      ).animate(
        CurvedAnimation(
          parent: _controller,
          curve: Curves.linear,
        ),
      );

      _animation!.addListener(() {
        setState(() {});
      });

      _controller.addStatusListener((status) {
        if (status == AnimationStatus.completed && widget.onFinal != null) {
          widget.onFinal!();
        }
      });

      _controller.forward();
    });
  }

  @override
  void dispose() {
    _controller.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return Transform.translate(
      offset: Offset(_animation?.value ?? 0, 0),
      child: FractionalTranslation(
        translation: Offset(1, 0),
        child: SizedBox(
          key: _key,
          child: widget.child,
        ),
      ),
    );
  }
}
